package com.p2p.terminal.controller;

import java.awt.im.spi.InputMethod;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.p2p.account.po.Agent;
import com.p2p.account.service.AgentService;
import com.p2p.common.cache.CacheManager;
import com.p2p.common.constants.Message;
import com.p2p.common.enums.ResponseEnum;
import com.p2p.common.utils.BeanUtil;
import com.p2p.common.utils.ExcelUtil;
import com.p2p.common.utils.PageUtil;
import com.p2p.common.utils.ParamUtils;
import com.p2p.common.utils.ResMessage;
import com.p2p.common.utils.StringUtils;
import com.p2p.terminal.po.P2pDailyData;
import com.p2p.terminal.service.P2pDailyDataService;
import com.p2p.terminal.vo.AgentTree;
import com.p2p.terminal.vo.DailyDataCondition;
import com.p2p.terminal.vo.P2pDailyResponse;
import com.p2p.wallet.service.WalletService;

@RestController
@RequestMapping(value = "terminal")
public class P2pDailyDataController {

	@Autowired
	private P2pDailyDataService p2pDailyDataService;

	@Autowired
	private WalletService walletService;

	@Autowired
	private AgentService agentService;

	/**
	 * 获取每日数据
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "selectDailyData", method = RequestMethod.POST)
	public ResMessage<P2pDailyResponse> selectDailyData(DailyDataCondition dataCondition) {
		EntityWrapper<P2pDailyData> dataWrapper = new EntityWrapper<P2pDailyData>();
		Long agentId = dataCondition.getAgentId();
		Integer agentLevel = dataCondition.getAgentLevel();
		String coinType = dataCondition.getCoinType();
		String connectionPool = dataCondition.getConnectionPool();
		String startTime = dataCondition.getStartTime();
		String endTime = dataCondition.getEndTime();
		Integer showZero = dataCondition.getShowZero();

		Integer pageIndex = dataCondition.getPageIndex();
		Integer pageSize = dataCondition.getPageSize();
		String sortLineName = dataCondition.getSort();
		String orderType = dataCondition.getOrder();

		if (agentId != 0l) {
			HashMap<String, Set<Long>> cache = (HashMap<String, Set<Long>>) CacheManager.getInstance()
					.getCache("agent_message");
			Set<Long> set = cache.get(StringUtils.Long2String(agentId));
			dataWrapper.in("agent_id", set);
		}
		if (!("0".equals(coinType)) && !StringUtils.isEmpty(coinType)) {
			dataWrapper.eq("coin_type", coinType);
		}
		if (!("0".equals(connectionPool)) && !StringUtils.isEmpty(coinType)) {
			dataWrapper.eq("connection_pool", connectionPool);
		}
		if (0 == showZero) {
			dataWrapper.ne("terminal_total_count", 0);
		}

		dataWrapper.between("date_time", startTime + " 00:00:00", endTime + " 23:00:00");
		// dataWrapper.between("date_time", startTime, endTime);

		Page<P2pDailyData> page = null;
		if (StringUtils.isEmpty(sortLineName)) {
			page = new Page<P2pDailyData>(pageIndex, pageSize);
		} else {
			page = new Page<P2pDailyData>(pageIndex, pageSize, sortLineName);
			page.setAsc(PageUtil.isAsc(orderType));
		}

		page = p2pDailyDataService.selectPage(page, dataWrapper);
		List<P2pDailyData> originalData = page.getRecords();
		// TODO 根据代理商编号和代理商名字查询当前在线终端数和最近一个小时的实时数据。（每隔十分钟一次数据）
		ArrayList<P2pDailyResponse> responses = new ArrayList<P2pDailyResponse>();

		originalData.forEach(item -> {
			P2pDailyResponse p2pDailyResponse = new P2pDailyResponse();

			BeanUtil.copyPropertiesNotForce(p2pDailyResponse, item);

			double terminalTotalCount = item.getTerminalTotalCount();
			double terminalInvalidCount = item.getTerminalInvalidCount();
			DecimalFormat df = new DecimalFormat("0.00");
			String round = "";
			if (terminalTotalCount == 0) {
				round = "0%";
			} else if (terminalInvalidCount == 0) {
				round = "100%";
			} else {
				round = df.format(terminalInvalidCount / terminalTotalCount * 100) + "%";
			}

			p2pDailyResponse.setValidPercent(round);

			// TODO 查询数据库

			Integer[] randomCommon = randomCommon(1, 10, 6);
			List<Integer> onlineStatus = Arrays.asList(randomCommon);
			p2pDailyResponse.setCurrentOnlineCount(onlineStatus.get(onlineStatus.size() - 1));
			p2pDailyResponse.setCurrentOnlineStatus(onlineStatus);

			responses.add(p2pDailyResponse);

		});

		return new ResMessage<>(responses, ResponseEnum.SUCCESS.getMsg(), true, page.getTotal());

	}

	/**
	 * 获取每日数据
	 *
	 * @param request
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value = "exportDailyData", method = RequestMethod.GET)
	public Message exportDailyData(HttpServletRequest request, HttpServletResponse response) throws Exception {

		EntityWrapper<P2pDailyData> dataWrapper = new EntityWrapper<P2pDailyData>();

		Long agentId = StringUtils.String2Long(ParamUtils.getParameter(request, "agentId"));

		String coinType = ParamUtils.getParameter(request, "coinType");
		String connectionPool = ParamUtils.getParameter(request, "connectionPool");
		String startTime = ParamUtils.getParameter(request, "startTime");
		String endTime = ParamUtils.getParameter(request, "endTime");
		Integer showZero = ParamUtils.getIntegerParameter(request, "showZero", 0);

		if (agentId != 0l) {
			HashMap<String, Set<Long>> cache = (HashMap<String, Set<Long>>) CacheManager.getInstance()
					.getCache("agent_message");
			Set<Long> set = cache.get(StringUtils.Long2String(agentId));
			dataWrapper.in("agent_id", set);
		}
		if (!("0".equals(coinType)) && !StringUtils.isEmpty(coinType)) {
			dataWrapper.eq("coin_type", coinType);
		}
		if (!("0".equals(connectionPool)) && !StringUtils.isEmpty(coinType)) {
			dataWrapper.eq("connection_pool", connectionPool);
		}
		if (0 == showZero) {
			dataWrapper.ne("terminal_total_count", 0);
		}

		dataWrapper.between("date_time", startTime + " 00:00:00", endTime + " 23:00:00");

		List<P2pDailyData> selectList = p2pDailyDataService.selectList(dataWrapper);

		String fileName = "每日数据" + System.currentTimeMillis();

		List<Map<String, Object>> list = tempCreateExcelRecord(selectList);
		// 列名
		String columnNames[] = { "日期", "编号", "代理", "种类", "外网IP", "路由Mac", "有效提交", "总终端", "无效终端", "异常终端", "特殊终端", "启动次数",
				"启动成功", "运行30", "运行60", "挖矿30", "挖矿60", "忙次数" };

		// 对应map的key
		String keys[] = { "dateTime", "agentId", "agentName", "coinType", "connectionPool", "coinCount",
				"validSubmitCount", "terminalTotalCount", "terminalInvalidCount", "terminalErrorCount",
				"terminalSpecialCount", "dayPrice", "predictIncome", "monthTotalIncome", "monthValidIncome", "ipCount",
				"errorSubmitCount", "errorCount", "connectionError", "recentSubmitTime", "updateTime",
				"startTotalCount", "startSuccessCount", "run30", "run60", "mining30", "mining60", "busyCount" };
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			Workbook workbook = ExcelUtil.createWorkBook(list, keys, keys);
			workbook.write(os);
			// test1(workbook);
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] content = os.toByteArray();
		InputStream is = new ByteArrayInputStream(content);
		// 设置response参数，可以打开下载页面
		response.reset();
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
		response.setHeader("Content-Disposition",
				"attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
		ServletOutputStream out = response.getOutputStream();
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(out);
			byte[] buff = new byte[40960];
			int bytesRead;
			// Simple read/write loop.
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
		} catch (final IOException e) {
			throw e;
		} finally {
			if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
		}
		return null;

	}

	private List<Map<String, Object>> tempCreateExcelRecord(List<P2pDailyData> projects) {
		List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sheetName", "sheet1");
		listmap.add(map);
		P2pDailyData item = null;
		for (int j = 0; j < projects.size(); j++) {
			item = projects.get(j);

			Map<String, Object> mapValue = new HashMap<String, Object>();
			mapValue.put("dateTime", item.getDateTime());
			mapValue.put("agentId", item.getAgentId());
			mapValue.put("agentName", item.getAgentName());
			mapValue.put("coinType", item.getCoinType());
			mapValue.put("connectionPool", item.getConnectionPool());
			mapValue.put("coinCount", item.getCoinCount());
			mapValue.put("dayPrice", item.getDayPrice());
			mapValue.put("predictIncome", item.getPredictIncome());
			mapValue.put("monthTotalIncome", item.getMonthTotalIncome());
			mapValue.put("monthValidIncome", item.getMonthValidIncome());
			mapValue.put("ipCount", item.getIpCount());

			mapValue.put("connectionError", item.getConnectionError());
			mapValue.put("errorCount", item.getErrorCount());
			mapValue.put("errorSubmitCount", item.getErrorSubmitCount());
			mapValue.put("validSubmitCount", item.getValidSubmitCount());
			mapValue.put("terminalTotalCount", item.getTerminalTotalCount());
			mapValue.put("terminalInvalidCount", item.getTerminalInvalidCount());
			mapValue.put("terminalErrorCount", item.getTerminalErrorCount());
			mapValue.put("terminalSpecialCount", item.getTerminalSpecialCount());
			mapValue.put("startTotalCount", item.getStartTotalCount());
			mapValue.put("startSuccessCount", item.getStartSuccessCount());
			mapValue.put("run30", item.getRun30());
			mapValue.put("run60", item.getRun60());
			mapValue.put("mining30", item.getMining30());
			mapValue.put("mining60", item.getMining60());
			mapValue.put("busyCount", item.getBusyCount());

			mapValue.put("recentSubmitTime", item.getRecentSubmitTime());
			mapValue.put("updateTime", item.getUpdateTime());
			listmap.add(mapValue);
		}
		return listmap;
	}

	public Integer[] randomCommon(int min, int max, int n) {

		Random ra = new Random();
		Integer[] result = new Integer[n];
		for (int i = 0; i < n; i++) {
			result[i] = ra.nextInt(max) - min + 2;
		}

		return result;
	}

	/**
	 * 获取代理商数据
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "selectAgentTree", method = RequestMethod.GET)
	public Message selectAgentTree() {

		AgentTree agentTree = new AgentTree("全部", 0l);
		ArrayList<AgentTree> firstAgent = new ArrayList<AgentTree>();
		List<Agent> totalAgents = agentService.selectList(new EntityWrapper<Agent>().eq("status", 1));

		totalAgents.stream().filter(item -> item.getAgentLevel() == 1).forEach(item -> {
			String code = item.getAgentCode();
			Long agentId = Long.parseLong(code);

			AgentTree agentTree1 = new AgentTree(item.getAgentCode(), agentId);
			ArrayList<AgentTree> agent1 = new ArrayList<AgentTree>();

			totalAgents.stream().filter(item2 -> item2.getAgentLevel() == 2 && agentId.equals(item2.getOneLevelId()))
					.forEach(item2 -> {
						
						ArrayList<AgentTree> agent2 = new ArrayList<AgentTree>();
						String code2 = item2.getAgentCode();
						Long agentId2 = Long.parseLong(code2);
						AgentTree agentTree2 = new AgentTree(code2, agentId2);

						totalAgents.stream()
								.filter(item3 -> item3.getAgentLevel() == 3&&agentId2.equals(item3.getTowLevelId()))
								.forEach(item3 -> {
									String code3 = item3.getAgentCode();
									Long agentId3 = Long.parseLong(code3);
									AgentTree agentTree3 = new AgentTree(code3, agentId3);
									agent2.add(agentTree3);

								});
						agentTree2.setChildren(agent2);
						agent1.add(agentTree2);

					});
			agentTree1.setChildren(agent1);
			firstAgent.add(agentTree1);
		});
		agentTree.setChildren(firstAgent);
		return new Message(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), agentTree);

	}
}
